<!DOCTYPE html>
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
  <meta name="description" content="刘清政">
  <meta name="keyword" content="hexo-theme">
  
    <link rel="shortcut icon" href="/css/images/logo.png">
  
  <title>
    
      1-Python中的GIL | Justin-刘清政的博客
    
  </title>
  <link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
  <link href="//cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.css" rel="stylesheet">
  <link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/tomorrow.min.css" rel="stylesheet">
  
<link rel="stylesheet" href="/css/style.css">

  
    
<link rel="stylesheet" href="/css/plugins/gitment.css">

  
  <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/geopattern/1.2.3/js/geopattern.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.js"></script>
  
    
<script src="/js/qrious.js"></script>

  
  
    
<script src="/js/gitment.js"></script>

  
  

  
<meta name="generator" content="Hexo 4.2.0"></head>
<div class="wechat-share">
  <img src="/css/images/logo.png" />
</div>

  <body>
    <header class="header fixed-header">
  <div class="header-container">
    <a class="home-link" href="/">
      <div class="logo"></div>
      <span>Justin-刘清政的博客</span>
    </a>
    <ul class="right-list">
      
        <li class="list-item">
          
            <a href="/" class="item-link">主页</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/tags/" class="item-link">标签</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/archives/" class="item-link">归档</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/about/" class="item-link">关于我</a>
          
        </li>
      
    </ul>
    <div class="menu">
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
    </div>
    <div class="menu-mask">
      <ul class="menu-list">
        
          <li class="menu-item">
            
              <a href="/" class="menu-link">主页</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/tags/" class="menu-link">标签</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/archives/" class="menu-link">归档</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/about/" class="menu-link">关于我</a>
            
          </li>
        
      </ul>
    </div>
  </div>
</header>

    <div id="article-banner">
  <h2>1-Python中的GIL</h2>



  <p class="post-date">2020-03-25</p>
    <!-- 不蒜子统计 -->
    <span id="busuanzi_container_page_pv" style='display:none' class="">
        <i class="icon-smile icon"></i> 阅读数：<span id="busuanzi_value_page_pv"></span>次
    </span>
  <div class="arrow-down">
    <a href="javascript:;"></a>
  </div>
</div>
<main class="app-body flex-box">
  <!-- Article START -->
  <article class="post-article">
    <section class="markdown-content"><p>之前我们已经了解了很多进程相关的理论知识，了解进程是什么应该不再困难了，刚刚我们已经了解了，运行中的程序就是一个进程。所有的进程都是通过它的父进程来创建的。因此，运行起来的python程序也是一个进程，那么我们也可以在程序中再创建进程。多个进程可以实现并发效果，也就是说，当我们的程序中存在多个进程的时候，在某些时候，就会让程序的执行速度变快。以我们之前所学的知识，并不能实现创建进程这个功能，所以我们就需要借助python中强大的模块。</p>
<h1 id="一、multiprocess模块"><a href="#一、multiprocess模块" class="headerlink" title="一、multiprocess模块"></a>一、multiprocess模块</h1><p>仔细说来，multiprocess不是一个模块而是python中一个操作、管理进程的包。 之所以叫multi是取自multiple的多功能的意思,在这个包中几乎包含了和进程有关的所有子模块。由于提供的子模块非常多，为了方便大家归类记忆，我将这部分大致分为四个部分：创建进程部分，进程同步部分，进程池部分，进程之间数据共享。</p>
<h1 id="二、multiprocess-process模块"><a href="#二、multiprocess-process模块" class="headerlink" title="二、multiprocess.process模块"></a>二、multiprocess.process模块</h1><p>process模块是一个创建进程的模块，借助这个模块，就可以完成进程的创建。</p>
<h1 id="三、process模块介绍"><a href="#三、process模块介绍" class="headerlink" title="三、process模块介绍"></a>三、process模块介绍</h1><p><code>Process([group [, target [, name [, args [, kwargs]]]]])</code>，由该类实例化得到的对象，表示一个子进程中的任务（尚未启动）</p>
<p>强调：</p>
<ol>
<li>需要使用关键字的方式来指定参数</li>
<li>args指定的为传给target函数的位置参数，是一个元组形式，必须有逗号</li>
</ol>
<p>参数介绍：</p>
<ul>
<li>group参数未使用，值始终为None</li>
<li>target表示调用对象，即子进程要执行的任务</li>
<li>args表示调用对象的位置参数元组，<code>args=(1,2,&#39;egon&#39;,)</code></li>
<li>kwargs表示调用对象的字典，<code>kwargs={&#39;name&#39;:&#39;egon&#39;,&#39;age&#39;:18}</code></li>
<li>name为子进程的名称</li>
</ul>
<h2 id="3-1-方法介绍"><a href="#3-1-方法介绍" class="headerlink" title="3.1 方法介绍"></a>3.1 方法介绍</h2><ul>
<li><code>p.start()</code>：启动进程，并调用该子进程中的p.run()</li>
<li><code>p.run()</code>：进程启动时运行的方法，正是它去调用target指定的函数，我们自定义类的类中一定要实现该方法</li>
<li><code>p.terminate()</code>：强制终止进程p，不会进行任何清理操作，如果p创建了子进程，该子进程就成了僵尸进程，使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放，进而导致死锁</li>
<li><code>p.is_alive()</code>：如果p仍然运行，返回True</li>
<li><code>p.join([timeout])</code>：主线程等待p终止（强调：是主线程处于等的状态，而p是处于运行的状态）。timeout是可选的超时时间，需要强调的是，p.join只能join住start开启的进程，而不能join住run开启的进程</li>
</ul>
<h2 id="3-2-属性介绍"><a href="#3-2-属性介绍" class="headerlink" title="3.2 属性介绍"></a>3.2 属性介绍</h2><ul>
<li><code>p.daemon</code>：默认值为False，如果设为True，代表p为后台运行的守护进程，当p的父进程终止时，p也随之终止，并且设定为True后，p不能创建自己的新进程，必须在<code>p.start()</code>之前设置</li>
<li><code>p.name</code>：进程的名称</li>
<li><code>p.pid</code>：进程的pid</li>
<li><code>p.exitcode</code>：进程在运行时为None、如果为–N，表示被信号N结束(了解即可)</li>
<li><code>p.authkey</code>：进程的身份验证键,默认是由<code>os.urandom()</code>随机生成的32字符的字符串。这个键的用途是为涉及网络连接的底层进程间通信提供安全性，这类连接只有在具有相同的身份验证键时才能成功（了解即可）</li>
</ul>
<h2 id="3-3-在windows中使用process模块的注意事项"><a href="#3-3-在windows中使用process模块的注意事项" class="headerlink" title="3.3 在windows中使用process模块的注意事项"></a>3.3 在windows中使用process模块的注意事项</h2><p>在Windows操作系统中由于没有fork(linux操作系统中创建进程的机制)，在创建子进程的时候会自动 import 启动它的这个文件，而在 import 的时候又执行了整个文件。因此如果将process()直接写在文件中就会无限递归创建子进程报错。所以必须把创建子进程的部分使用<code>if \_\_name\_\_ ==&#39;\_\_main\_\_&#39;</code> 判断保护起来，import 的时候，就不会递归运行了。</p>
<h1 id="四、使用process模块创建进程"><a href="#四、使用process模块创建进程" class="headerlink" title="四、使用process模块创建进程"></a>四、使用process模块创建进程</h1><p>在一个python进程中开启子进程，start方法和并发效果。</p>
<h2 id="4-1-在Python中启动的第一个子进程"><a href="#4-1-在Python中启动的第一个子进程" class="headerlink" title="4.1 在Python中启动的第一个子进程"></a>4.1 在Python中启动的第一个子进程</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">f</span><span class="params">(name)</span>:</span></span><br><span class="line">    print(<span class="string">'hello'</span>, name)</span><br><span class="line">    print(<span class="string">'我是子进程'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line">    p = Process(target=f, args=(<span class="string">'bob'</span>,))</span><br><span class="line">    p.start()</span><br><span class="line">    time.sleep(<span class="number">1</span>)</span><br><span class="line">    print(<span class="string">'执行主进程的内容了'</span>)</span><br></pre></td></tr></table></figure>

<h2 id="4-2-join方法"><a href="#4-2-join方法" class="headerlink" title="4.2 join方法"></a>4.2 join方法</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">f</span><span class="params">(name)</span>:</span></span><br><span class="line">    print(<span class="string">'hello'</span>, name)</span><br><span class="line">    time.sleep(<span class="number">1</span>)</span><br><span class="line">    print(<span class="string">'我是子进程'</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line">    p = Process(target=f, args=(<span class="string">'bob'</span>,))</span><br><span class="line">    p.start()</span><br><span class="line">    <span class="comment"># p.join()</span></span><br><span class="line">    print(<span class="string">'我是父进程'</span>)</span><br></pre></td></tr></table></figure>

<h2 id="4-3-查看主进程和子进程的进程号"><a href="#4-3-查看主进程和子进程的进程号" class="headerlink" title="4.3 查看主进程和子进程的进程号"></a>4.3 查看主进程和子进程的进程号</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">f</span><span class="params">(x)</span>:</span></span><br><span class="line">    print(<span class="string">'子进程id ：'</span>,os.getpid(),<span class="string">'父进程id ：'</span>,os.getppid())</span><br><span class="line">    <span class="keyword">return</span> x*x</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line">    print(<span class="string">'主进程id ：'</span>, os.getpid())</span><br><span class="line">    p_lst = []</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">5</span>):</span><br><span class="line">        p = Process(target=f, args=(i,))</span><br><span class="line">        p.start()</span><br></pre></td></tr></table></figure>

<p>进阶，多个进程同时运行（注意，子进程的执行顺序不是根据启动顺序决定的）</p>
<h2 id="4-4-多个进程同时运行"><a href="#4-4-多个进程同时运行" class="headerlink" title="4.4 多个进程同时运行"></a>4.4 多个进程同时运行</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">f</span><span class="params">(name)</span>:</span></span><br><span class="line">    print(<span class="string">'hello'</span>, name)</span><br><span class="line">    time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line">    p_lst = []</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">5</span>):</span><br><span class="line">        p = Process(target=f, args=(<span class="string">'bob'</span>,))</span><br><span class="line">        p.start()</span><br><span class="line">        p_lst.append(p)</span><br></pre></td></tr></table></figure>

<h2 id="4-5-多个进程同时运行，再谈join方法-1"><a href="#4-5-多个进程同时运行，再谈join方法-1" class="headerlink" title="4.5 多个进程同时运行，再谈join方法(1)"></a>4.5 多个进程同时运行，再谈join方法(1)</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">f</span><span class="params">(name)</span>:</span></span><br><span class="line">    print(<span class="string">'hello'</span>, name)</span><br><span class="line">    time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line">    p_lst = []</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">5</span>):</span><br><span class="line">        p = Process(target=f, args=(<span class="string">'bob'</span>,))</span><br><span class="line">        p.start()</span><br><span class="line">        p_lst.append(p)</span><br><span class="line">        p.join()</span><br><span class="line">    <span class="comment"># [p.join() for p in p_lst]</span></span><br><span class="line">    print(<span class="string">'父进程在执行'</span>)</span><br></pre></td></tr></table></figure>

<h2 id="4-6-多个进程同时运行，再谈join方法-2"><a href="#4-6-多个进程同时运行，再谈join方法-2" class="headerlink" title="4.6 多个进程同时运行，再谈join方法(2)"></a>4.6 多个进程同时运行，再谈join方法(2)</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">f</span><span class="params">(name)</span>:</span></span><br><span class="line">    print(<span class="string">'hello'</span>, name)</span><br><span class="line">    time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line">    p_lst = []</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">5</span>):</span><br><span class="line">        p = Process(target=f, args=(<span class="string">'bob'</span>,))</span><br><span class="line">        p.start()</span><br><span class="line">        p_lst.append(p)</span><br><span class="line">    <span class="comment"># [p.join() for p in p_lst]</span></span><br><span class="line">    print(<span class="string">'父进程在执行'</span>)</span><br></pre></td></tr></table></figure>

<p>除了上面这些开启进程的方法，还有一种以继承Process类的形式开启进程的方式</p>
<h2 id="4-7-通过继承Process类开启进程"><a href="#4-7-通过继承Process类开启进程" class="headerlink" title="4.7 通过继承Process类开启进程"></a>4.7 通过继承Process类开启进程</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyProcess</span><span class="params">(Process)</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self,name)</span>:</span></span><br><span class="line">        super().__init__()</span><br><span class="line">        self.name=name</span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">run</span><span class="params">(self)</span>:</span></span><br><span class="line">        print(os.getpid())</span><br><span class="line">        print(<span class="string">'%s 正在和女主播聊天'</span> %self.name)</span><br><span class="line"></span><br><span class="line">p1=MyProcess(<span class="string">'wupeiqi'</span>)</span><br><span class="line">p2=MyProcess(<span class="string">'yuanhao'</span>)</span><br><span class="line">p3=MyProcess(<span class="string">'nezha'</span>)</span><br><span class="line"></span><br><span class="line">p1.start() <span class="comment"># start会自动调用run</span></span><br><span class="line">p2.start()</span><br><span class="line"><span class="comment"># p2.run()</span></span><br><span class="line">p3.start()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">p1.join()</span><br><span class="line">p2.join()</span><br><span class="line">p3.join()</span><br><span class="line"></span><br><span class="line">print(<span class="string">'主线程'</span>)</span><br></pre></td></tr></table></figure>

<p>进程之间的数据隔离问题</p>
<h2 id="4-8-进程之间的数据隔离问题"><a href="#4-8-进程之间的数据隔离问题" class="headerlink" title="4.8 进程之间的数据隔离问题"></a>4.8 进程之间的数据隔离问题</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">work</span><span class="params">()</span>:</span></span><br><span class="line">    <span class="keyword">global</span> n</span><br><span class="line">    n=<span class="number">0</span></span><br><span class="line">    print(<span class="string">'子进程内: '</span>,n)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line">    n = <span class="number">100</span></span><br><span class="line">    p=Process(target=work)</span><br><span class="line">    p.start()</span><br><span class="line">    print(<span class="string">'主进程内: '</span>,n)</span><br></pre></td></tr></table></figure>

<h1 id="五、守护进程"><a href="#五、守护进程" class="headerlink" title="五、守护进程"></a>五、守护进程</h1><p>会随着主进程的结束而结束。</p>
<p>主进程创建守护进程</p>
<p>　　其一：守护进程会在主进程代码执行结束后就终止</p>
<p>　　其二：守护进程内无法再开启子进程,否则抛出异常：<code>AssertionError: daemonic processes are not allowed to have children</code></p>
<p>注意：<strong>进程之间是互相独立的，主进程代码运行结束，守护进程随即终止。</strong></p>
<h2 id="5-1-守护进程的启动"><a href="#5-1-守护进程的启动" class="headerlink" title="5.1 守护进程的启动"></a>5.1 守护进程的启动</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Myprocess</span><span class="params">(Process)</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self,person)</span>:</span></span><br><span class="line">        super().__init__()</span><br><span class="line">        self.person = person</span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">run</span><span class="params">(self)</span>:</span></span><br><span class="line">        print(os.getpid(),self.name)</span><br><span class="line">        print(<span class="string">'%s正在和女主播聊天'</span> %self.person)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">p=Myprocess(<span class="string">'哪吒'</span>)</span><br><span class="line">p.daemon=<span class="literal">True</span> <span class="comment"># 一定要在p.start()前设置,设置p为守护进程,禁止p创建子进程,并且父进程代码执行结束,p即终止运行</span></span><br><span class="line">p.start()</span><br><span class="line">time.sleep(<span class="number">10</span>)  <span class="comment"># 在sleep时查看进程id对应的进程ps -ef|grep id</span></span><br><span class="line">print(<span class="string">'主'</span>)</span><br></pre></td></tr></table></figure>

<h2 id="5-2-主进程代码执行结束守护进程立即结束"><a href="#5-2-主进程代码执行结束守护进程立即结束" class="headerlink" title="5.2 主进程代码执行结束守护进程立即结束"></a>5.2 主进程代码执行结束守护进程立即结束</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">foo</span><span class="params">()</span>:</span></span><br><span class="line">    print(<span class="number">123</span>)</span><br><span class="line">    time.sleep(<span class="number">1</span>)</span><br><span class="line">    print(<span class="string">"end123"</span>)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">bar</span><span class="params">()</span>:</span></span><br><span class="line">    print(<span class="number">456</span>)</span><br><span class="line">    time.sleep(<span class="number">3</span>)</span><br><span class="line">    print(<span class="string">"end456"</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">p1=Process(target=foo)</span><br><span class="line">p2=Process(target=bar)</span><br><span class="line"></span><br><span class="line">p1.daemon=<span class="literal">True</span></span><br><span class="line">p1.start()</span><br><span class="line">p2.start()</span><br><span class="line">time.sleep(<span class="number">0.1</span>)</span><br><span class="line">print(<span class="string">"main-------"</span>)  <span class="comment"># 打印该行则主进程代码结束,则守护进程p1应该被终止.#可能会有p1任务执行的打印信息123,因为主进程打印main----时,p1也执行了,但是随即被终止.</span></span><br></pre></td></tr></table></figure>

<h1 id="六、socket聊天并发实例"><a href="#六、socket聊天并发实例" class="headerlink" title="六、socket聊天并发实例"></a>六、socket聊天并发实例</h1><h2 id="6-1-使用多进程实现socket聊天并发-server端"><a href="#6-1-使用多进程实现socket聊天并发-server端" class="headerlink" title="6.1 使用多进程实现socket聊天并发-server端"></a>6.1 使用多进程实现socket聊天并发-server端</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> socket <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line">server=socket(AF_INET,SOCK_STREAM)</span><br><span class="line">server.setsockopt(SOL_SOCKET,SO_REUSEADDR,<span class="number">1</span>)</span><br><span class="line">server.bind((<span class="string">'127.0.0.1'</span>,<span class="number">8080</span>))</span><br><span class="line">server.listen(<span class="number">5</span>)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">talk</span><span class="params">(conn,client_addr)</span>:</span></span><br><span class="line">    <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">        <span class="keyword">try</span>:</span><br><span class="line">            msg=conn.recv(<span class="number">1024</span>)</span><br><span class="line">            <span class="keyword">if</span> <span class="keyword">not</span> msg:<span class="keyword">break</span></span><br><span class="line">            conn.send(msg.upper())</span><br><span class="line">        <span class="keyword">except</span> Exception:</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>: <span class="comment"># windows下start进程一定要写到这下面</span></span><br><span class="line">    <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">        conn,client_addr=server.accept()</span><br><span class="line">        p=Process(target=talk,args=(conn,client_addr))</span><br><span class="line">        p.start()</span><br></pre></td></tr></table></figure>

<h2 id="6-2-使用多进程实现socket聊天并发-client端"><a href="#6-2-使用多进程实现socket聊天并发-client端" class="headerlink" title="6.2 使用多进程实现socket聊天并发-client端"></a>6.2 使用多进程实现socket聊天并发-client端</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> socket <span class="keyword">import</span> *</span><br><span class="line"></span><br><span class="line">client=socket(AF_INET,SOCK_STREAM)</span><br><span class="line">client.connect((<span class="string">'127.0.0.1'</span>,<span class="number">8080</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">    msg=input(<span class="string">'&gt;&gt;: '</span>).strip()</span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">not</span> msg:<span class="keyword">continue</span></span><br><span class="line"></span><br><span class="line">    client.send(msg.encode(<span class="string">'utf-8'</span>))</span><br><span class="line">    msg=client.recv(<span class="number">1024</span>)</span><br><span class="line">    print(msg.decode(<span class="string">'utf-8'</span>))</span><br></pre></td></tr></table></figure>

<h1 id="七、多进程中的其他方法"><a href="#七、多进程中的其他方法" class="headerlink" title="七、多进程中的其他方法"></a>七、多进程中的其他方法</h1><h2 id="7-1-进程对象的其他方法：terminate和is-alive"><a href="#7-1-进程对象的其他方法：terminate和is-alive" class="headerlink" title="7.1 进程对象的其他方法：terminate和is_alive"></a>7.1 进程对象的其他方法：terminate和is_alive</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Myprocess</span><span class="params">(Process)</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self,person)</span>:</span></span><br><span class="line">        self.name=person</span><br><span class="line">        super().__init__()</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">run</span><span class="params">(self)</span>:</span></span><br><span class="line">        print(<span class="string">'%s正在和网红脸聊天'</span> %self.name)</span><br><span class="line">        time.sleep(random.randrange(<span class="number">1</span>,<span class="number">5</span>))</span><br><span class="line">        print(<span class="string">'%s还在和网红脸聊天'</span> %self.name)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">p1=Myprocess(<span class="string">'哪吒'</span>)</span><br><span class="line">p1.start()</span><br><span class="line"></span><br><span class="line">p1.terminate()<span class="comment">#关闭进程,不会立即关闭,所以is_alive立刻查看的结果可能还是存活</span></span><br><span class="line">print(p1.is_alive()) <span class="comment">#结果为True</span></span><br><span class="line"></span><br><span class="line">print(<span class="string">'开始'</span>)</span><br><span class="line">print(p1.is_alive()) <span class="comment">#结果为False</span></span><br></pre></td></tr></table></figure>

<h2 id="7-2-进程对象的其他属性：pid和name"><a href="#7-2-进程对象的其他属性：pid和name" class="headerlink" title="7.2 进程对象的其他属性：pid和name"></a>7.2 进程对象的其他属性：pid和name</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Myprocess</span><span class="params">(Process)</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self,person)</span>:</span></span><br><span class="line">        self.name=person   <span class="comment"># name属性是Process中的属性，标示进程的名字</span></span><br><span class="line">        super().__init__()  <span class="comment"># 执行父类的初始化方法会覆盖name属性</span></span><br><span class="line">        <span class="comment"># self.name = person  # 在这里设置就可以修改进程名字了</span></span><br><span class="line">        <span class="comment"># self.person = person  # 如果不想覆盖进程名，就修改属性名称就可以了</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">run</span><span class="params">(self)</span>:</span></span><br><span class="line">        print(<span class="string">'%s正在和网红脸聊天'</span> %self.name)</span><br><span class="line">        <span class="comment"># print('%s正在和网红脸聊天' %self.person)</span></span><br><span class="line">        time.sleep(random.randrange(<span class="number">1</span>,<span class="number">5</span>))</span><br><span class="line">        print(<span class="string">'%s正在和网红脸聊天'</span> %self.name)</span><br><span class="line">        <span class="comment"># print('%s正在和网红脸聊天' %self.person)</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">p1=Myprocess(<span class="string">'哪吒'</span>)</span><br><span class="line">p1.start()</span><br><span class="line">print(p1.pid)    <span class="comment">#可以查看子进程的进程id</span></span><br></pre></td></tr></table></figure></section>
    <!-- Tags START -->
    
      <div class="tags">
        <span>Tags:</span>
        
  <a href="/tags#Python" >
    <span class="tag-code">Python</span>
  </a>

      </div>
    
    <!-- Tags END -->
    <!-- NAV START -->
    
  <div class="nav-container">
    <!-- reverse left and right to put prev and next in a more logic postition -->
    
      <a class="nav-left" href="/python/Python%E5%BC%82%E6%AD%A5IO%E5%B9%B6%E5%8F%91/3-IO%E6%93%8D%E4%BD%9C%E4%B8%8EIO%E6%A8%A1%E5%9E%8B/">
        <span class="nav-arrow">← </span>
        
          3-IO操作与IO模型
        
      </a>
    
    
      <a class="nav-right" href="/python/Python%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/9-%E8%BF%9B%E7%A8%8B%E9%97%B4%E9%80%9A%E4%BF%A1(multiprocess.Queue)/">
        
          1-Python中的GIL
        
        <span class="nav-arrow"> →</span>
      </a>
    
  </div>

    <!-- NAV END -->
    <!-- 打赏 START -->
    
      <div class="money-like">
        <div class="reward-btn">
          赏
          <span class="money-code">
            <span class="alipay-code">
              <div class="code-image"></div>
              <b>使用支付宝打赏</b>
            </span>
            <span class="wechat-code">
              <div class="code-image"></div>
              <b>使用微信打赏</b>
            </span>
          </span>
        </div>
        <p class="notice">点击上方按钮,请我喝杯咖啡！</p>
      </div>
    
    <!-- 打赏 END -->
    <!-- 二维码 START -->
    
      <div class="qrcode">
        <canvas id="share-qrcode"></canvas>
        <p class="notice">扫描二维码，分享此文章</p>
      </div>
    
    <!-- 二维码 END -->
    
      <!-- Gitment START -->
      <div id="comments"></div>
      <!-- Gitment END -->
    
  </article>
  <!-- Article END -->
  <!-- Catalog START -->
  
    <aside class="catalog-container">
  <div class="toc-main">
  <!-- 不蒜子统计 -->
    <strong class="toc-title">目录</strong>
    
      <ol class="toc-nav"><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#一、multiprocess模块"><span class="toc-nav-text">一、multiprocess模块</span></a></li><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#二、multiprocess-process模块"><span class="toc-nav-text">二、multiprocess.process模块</span></a></li><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#三、process模块介绍"><span class="toc-nav-text">三、process模块介绍</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#3-1-方法介绍"><span class="toc-nav-text">3.1 方法介绍</span></a></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#3-2-属性介绍"><span class="toc-nav-text">3.2 属性介绍</span></a></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#3-3-在windows中使用process模块的注意事项"><span class="toc-nav-text">3.3 在windows中使用process模块的注意事项</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#四、使用process模块创建进程"><span class="toc-nav-text">四、使用process模块创建进程</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#4-1-在Python中启动的第一个子进程"><span class="toc-nav-text">4.1 在Python中启动的第一个子进程</span></a></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#4-2-join方法"><span class="toc-nav-text">4.2 join方法</span></a></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#4-3-查看主进程和子进程的进程号"><span class="toc-nav-text">4.3 查看主进程和子进程的进程号</span></a></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#4-4-多个进程同时运行"><span class="toc-nav-text">4.4 多个进程同时运行</span></a></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#4-5-多个进程同时运行，再谈join方法-1"><span class="toc-nav-text">4.5 多个进程同时运行，再谈join方法(1)</span></a></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#4-6-多个进程同时运行，再谈join方法-2"><span class="toc-nav-text">4.6 多个进程同时运行，再谈join方法(2)</span></a></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#4-7-通过继承Process类开启进程"><span class="toc-nav-text">4.7 通过继承Process类开启进程</span></a></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#4-8-进程之间的数据隔离问题"><span class="toc-nav-text">4.8 进程之间的数据隔离问题</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#五、守护进程"><span class="toc-nav-text">五、守护进程</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#5-1-守护进程的启动"><span class="toc-nav-text">5.1 守护进程的启动</span></a></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#5-2-主进程代码执行结束守护进程立即结束"><span class="toc-nav-text">5.2 主进程代码执行结束守护进程立即结束</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#六、socket聊天并发实例"><span class="toc-nav-text">六、socket聊天并发实例</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#6-1-使用多进程实现socket聊天并发-server端"><span class="toc-nav-text">6.1 使用多进程实现socket聊天并发-server端</span></a></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#6-2-使用多进程实现socket聊天并发-client端"><span class="toc-nav-text">6.2 使用多进程实现socket聊天并发-client端</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#七、多进程中的其他方法"><span class="toc-nav-text">七、多进程中的其他方法</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#7-1-进程对象的其他方法：terminate和is-alive"><span class="toc-nav-text">7.1 进程对象的其他方法：terminate和is_alive</span></a></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#7-2-进程对象的其他属性：pid和name"><span class="toc-nav-text">7.2 进程对象的其他属性：pid和name</span></a></li></ol></li></ol>
    
  </div>
</aside>
  
  <!-- Catalog END -->
</main>

<script>
  (function () {
    var url = 'http://www.liuqingzheng.top/python/Python并发编程/7-开启多进程(multiprocess.process)/';
    var banner = ''
    if (banner !== '' && banner !== 'undefined' && banner !== 'null') {
      $('#article-banner').css({
        'background-image': 'url(' + banner + ')'
      })
    } else {
      $('#article-banner').geopattern(url)
    }
    $('.header').removeClass('fixed-header')

    // error image
    $(".markdown-content img").on('error', function() {
      $(this).attr('src', 'http://file.muyutech.com/error-img.png')
      $(this).css({
        'cursor': 'default'
      })
    })

    // zoom image
    $(".markdown-content img").on('click', function() {
      var src = $(this).attr('src')
      if (src !== 'http://file.muyutech.com/error-img.png') {
        var imageW = $(this).width()
        var imageH = $(this).height()

        var zoom = ($(window).width() * 0.95 / imageW).toFixed(2)
        zoom = zoom < 1 ? 1 : zoom
        zoom = zoom > 2 ? 2 : zoom
        var transY = (($(window).height() - imageH) / 2).toFixed(2)

        $('body').append('<div class="image-view-wrap"><div class="image-view-inner"><img src="'+ src +'" /></div></div>')
        $('.image-view-wrap').addClass('wrap-active')
        $('.image-view-wrap img').css({
          'width': `${imageW}`,
          'transform': `translate3d(0, ${transY}px, 0) scale3d(${zoom}, ${zoom}, 1)`
        })
        $('html').css('overflow', 'hidden')

        $('.image-view-wrap').on('click', function() {
          $(this).remove()
          $('html').attr('style', '')
        })
      }
    })
  })();
</script>


  <script>
    var qr = new QRious({
      element: document.getElementById('share-qrcode'),
      value: document.location.href
    });
  </script>



  <script>
    var gitmentConfig = "liuqingzheng";
    if (gitmentConfig !== 'undefined') {
      var gitment = new Gitment({
        id: "1-Python中的GIL",
        owner: "liuqingzheng",
        repo: "FuckBlog",
        oauth: {
          client_id: "32a4076431cf39d0ecea",
          client_secret: "94484bd79b3346a949acb2fda3c8a76ce16990c6"
        },
        theme: {
          render(state, instance) {
            const container = document.createElement('div')
            container.lang = "en-US"
            container.className = 'gitment-container gitment-root-container'
            container.appendChild(instance.renderHeader(state, instance))
            container.appendChild(instance.renderEditor(state, instance))
            container.appendChild(instance.renderComments(state, instance))
            container.appendChild(instance.renderFooter(state, instance))
            return container;
          }
        }
      })
      gitment.render(document.getElementById('comments'))
    }
  </script>




    <div class="scroll-top">
  <span class="arrow-icon"></span>
</div>
    <footer class="app-footer">
<!-- 不蒜子统计 -->
<span id="busuanzi_container_site_pv">
     本站总访问量<span id="busuanzi_value_site_pv"></span>次
</span>
<span class="post-meta-divider">|</span>
<span id="busuanzi_container_site_uv" style='display:none'>
     本站访客数<span id="busuanzi_value_site_uv"></span>人
</span>
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>



  <p class="copyright">
    &copy; 2021 | Proudly powered by <a href="https://www.cnblogs.com/xiaoyuanqujing" target="_blank">小猿取经</a>
    <br>
    Theme by <a href="https://www.cnblogs.com/xiaoyuanqujing" target="_blank" rel="noopener">小猿取经</a>
  </p>
</footer>

<script>
  function async(u, c) {
    var d = document, t = 'script',
      o = d.createElement(t),
      s = d.getElementsByTagName(t)[0];
    o.src = u;
    if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); }
    s.parentNode.insertBefore(o, s);
  }
</script>
<script>
  async("//cdnjs.cloudflare.com/ajax/libs/fastclick/1.0.6/fastclick.min.js", function(){
    FastClick.attach(document.body);
  })
</script>

<script>
  var hasLine = 'true';
  async("//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js", function(){
    $('figure pre').each(function(i, block) {
      var figure = $(this).parents('figure');
      if (hasLine === 'false') {
        figure.find('.gutter').hide();
      }
      var lang = figure.attr('class').split(' ')[1] || 'code';
      var codeHtml = $(this).html();
      var codeTag = document.createElement('code');
      codeTag.className = lang;
      codeTag.innerHTML = codeHtml;
      $(this).attr('class', '').empty().html(codeTag);
      figure.attr('data-lang', lang.toUpperCase());
      hljs.highlightBlock(block);
    });
  })
</script>





<!-- Baidu Tongji -->

<script>
    var _baId = 'c5fd96eee1193585be191f318c3fa725';
    // Originial
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "//hm.baidu.com/hm.js?" + _baId;
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
</script>


<script src="/js/script.js"></script>


<script src="/js/search.js"></script>


<script src="/js/load.js"></script>



  <span class="local-search local-search-google local-search-plugin" style="right: 50px;top: 70px;;position:absolute;z-index:2;">
      <input type="search" placeholder="站内搜索" id="local-search-input" class="local-search-input-cls" style="">
      <div id="local-search-result" class="local-search-result-cls"></div>
  </span>


  </body>
</html>